package cn.wolfcode.shop.cloud.mq.listener;

import cn.wolfcode.shop.cloud.common.BusinessException;
import cn.wolfcode.shop.cloud.common.CodeMsg;
import cn.wolfcode.shop.cloud.common.JSONUtil;
import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.mq.DefaultSeckillOrderMsgSendCallback;
import cn.wolfcode.shop.cloud.mq.MQConstants;
import cn.wolfcode.shop.cloud.mq.msg.CreateSeckillOrderMsg;
import cn.wolfcode.shop.cloud.mq.msg.DelaySeckillOrderMsg;
import cn.wolfcode.shop.cloud.mq.msg.SeckillFailedMsg;
import cn.wolfcode.shop.cloud.mq.msg.SeckillSuccessMsg;
import cn.wolfcode.shop.cloud.service.IOrderInfoService;
import cn.wolfcode.shop.cloud.web.msg.SeckillServerCodeMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;

/**
 * Created by wolfcode-lanxw
 */
@RocketMQMessageListener(
        topic = MQConstants.SECKILL_ORDER_TOPIC,
        selectorExpression = MQConstants.CREATE_ORDER_TAG,
        consumerGroup = MQConstants.CREATE_ORDER_CONSUMER_GROUP
)
@Component
@Slf4j
public class CreateSeckillOrderMQListener implements RocketMQListener<CreateSeckillOrderMsg> {

    @Autowired
    private IOrderInfoService orderInfoService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void onMessage(CreateSeckillOrderMsg message) {
        log.info("[创建订单] 收到创建订单消息:{}", JSONUtil.toJSONString(message));

        try {
            // 消费创建订单消息, 进行真正的创建订单操作
            String orderNo = orderInfoService.seckillOrder(message.getSeckillId(), message.getUserId());
            // 订单创建成功, 发送订单创建成功消息, 通知客户端
            SeckillSuccessMsg successMsg = new SeckillSuccessMsg(orderNo, message.getUuid());
            // 发送订单创建成功消息
            rocketMQTemplate.asyncSend(MQConstants.SECKILL_SUCCESS_DEST, successMsg, new DefaultSeckillOrderMsgSendCallback());
            // 发送延迟消息: 检查订单是否超时未支付
            // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
            rocketMQTemplate.asyncSend(
                    MQConstants.DELAY_SECKILL_ORDER_DEST,
                    new GenericMessage<>(new DelaySeckillOrderMsg(message.getSeckillId(), orderNo)),
                    new DefaultSeckillOrderMsgSendCallback(), 2000, 16);
        } catch (Exception e) {
            BusinessException be = null;
            CodeMsg error = SeckillServerCodeMsg.DEFALUT_ERROR;
            if (e instanceof BusinessException) {
                be = (BusinessException) e;
                error = be.getCodeMsg();
            }
            // 订单创建失败: 通知前端用户, 回补 Redis 库存, 清除用户下单标记, 本地售完标记
            rocketMQTemplate.asyncSend(MQConstants.SECKILL_FAILED_DEST, new SeckillFailedMsg(message.getUuid(), error), new DefaultSeckillOrderMsgSendCallback());
            // 处理订单下单失败的情况
            orderInfoService.handleFailed(message.getSeckillId(), message.getUserId());
        }
    }
}
